package rollercoaster.commons;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;

import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;

import rollercoaster.environment.utils.Buffers;



public class Model {

	private short[] indices;
	private float[] vertices;
	private float[] normals;
	private float[] textures;
	private int[] vbos;
	private int vao;
	private int vbo;//vertices buffer object 
	private int nbo; //normals buffer object
	private int ibo;//indices buffer object
	private int tbo;//texture buffer object
	private int[] shaderAtrributes;

	private HashMap<String, Integer> geometries;
	
	private Material material;
	
	public Model(float[] indexedVertices2, float[] indexedNormals2,
			short[] convertIndices,float [] textures) {	
		this.vertices=indexedVertices2;
		this.normals=indexedNormals2;
		this.indices=convertIndices;
		this.textures=textures;
	}

	public float[] getTextures() {
		return textures;
	}

	public void setTextures(float[] textures) {
		this.textures = textures;
	}

	public short[] getIndices() {
		return indices;
	}

	
	public HashMap<String, Integer> getGeometries() {
		return geometries;
	}

	public float[] getVertices() {
		return vertices;
	}

	public float[] getNormals() {
		return normals;
	}
	

	public void setShaderAtrributes(int[] shaderAtrributes) {
		this.shaderAtrributes = shaderAtrributes;
	}

	public void setMaterial(Material material) {
		this.material = material;
	}
	
	

	public Material getMaterial() {
		return material;
	}

	public void initBuffers(GL2ES2 gl){
		
		vbos = new int[4];
		
		gl.glGenBuffers(4, vbos, 0);
		
		this.vbo=vbos[0];
		this.nbo=vbos[1];
		this.ibo=vbos[2];
		this.tbo=vbos[3];
		ByteBuffer byteData=Buffers.loadFloatBuffer(vertices);
		gl.glBindBuffer(GL.GL_ARRAY_BUFFER, this.vbo);
		gl.glBufferData(GL.GL_ARRAY_BUFFER, vertices.length*Buffers.SIZE_OF_FLOAT, byteData, GL.GL_STATIC_DRAW);
		
		ByteBuffer normalsData=Buffers.loadFloatBuffer(normals);
		gl.glBindBuffer(GL.GL_ARRAY_BUFFER, this.nbo);
		gl.glBufferData(GL.GL_ARRAY_BUFFER, normals.length*Buffers.SIZE_OF_FLOAT, normalsData, GL.GL_STATIC_DRAW);
		
		ByteBuffer textureData=Buffers.loadFloatBuffer(textures);
		gl.glBindBuffer(GL.GL_ARRAY_BUFFER, this.tbo);
		gl.glBufferData(GL.GL_ARRAY_BUFFER, textures.length*Buffers.SIZE_OF_FLOAT, textureData, GL.GL_STATIC_DRAW);
		
		ByteBuffer indicesBytes=Buffers.loadShortBuffer(indices);
		gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, this.ibo);
		gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.length*Buffers.SIZE_OF_SHORT, indicesBytes, GL.GL_STATIC_DRAW);
		
	}
	
	public void draw(GL2ES2 gl)
	{

		if(material!=null)material.apply(gl, shaderAtrributes[3]);

		gl.glEnableVertexAttribArray(shaderAtrributes[0]);
		gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo);
		gl.glVertexAttribPointer(shaderAtrributes[0], 3, GL2ES2.GL_FLOAT, false, 0, 0);

		gl.glEnableVertexAttribArray(shaderAtrributes[1]);
		gl.glBindBuffer(GL.GL_ARRAY_BUFFER, nbo);
		gl.glVertexAttribPointer(shaderAtrributes[1], 3, GL2ES2.GL_FLOAT, true, 0, 0);
		
		gl.glEnableVertexAttribArray(shaderAtrributes[2]);
		gl.glBindBuffer(GL.GL_ARRAY_BUFFER, tbo);
		gl.glVertexAttribPointer(shaderAtrributes[2], 2, GL2ES2.GL_FLOAT, true, 0, 0);
		
		gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, ibo);
		gl.glDrawElements(GL.GL_TRIANGLES, indices.length, GL.GL_UNSIGNED_SHORT, 0);
	}
}
